home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
CH_4.4
/
XFM
/
XFM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
6KB
|
282 lines
/*
* xfm.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/*
* XF(ast)M(oments)
*
* calculate moments, M, of a gray scale image up to m33,
* based on a filter array, Y, extracted from the imput image,
* and a mask CM:
*
* M = CM*Y*CM'; CM': transposed CM, *: matrix mult.
*
* ref: M. Hatamian,
* IEEE Trans. on Acoust., Speech and Signal Proc.,
* ASSP-34, 546 - 553, 1986;
* Proc of Digital Signal Proc. - 87,
* V. Cappellini & A. G. Constantinides, Eds.
* Elsevier Sci. Publ. B. V. (North Holland), 1987
*
* version based on M. Hatamian's code implementing recursion
* to obtain Y-matrix;
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "xfm.h"
#define ON 1
#define OFF 0
#define RESET ON /* reset graphics screen */
#define NO_RESET OFF
#undef DEBUG
extern char *optarg;
extern int optind, opterr;
extern short tiffInput; /* flag=0 if no ImageIn to set tags; else =1 */
int FILTER_TEST = OFF;
int WRITE_FILE = OFF;
void
fail_alloc (str, code)
char *str;
int code;
{
printf ("\n...memory alloc for %s failed\n", str);
exit (code);
}
/*
* usage of routine
*/
void
usage (char *progname)
{
progname = last_bs (progname);
printf ("USAGE: %s inimg [-d] [-w file] [-t] [-L]\n", progname);
printf ("\n%s iteratively evaluates moments of a convex shape up to 3rd order,\n\n", progname);
printf ("ARGUMENTS:\n");
printf (" inimg: input image filename (TIF)\n\n");
printf ("OPTIONS:\n");
printf (" -d: default mode: evaluate moments of binary region\n");
printf (" -w: write file (.mdt) to disk\n");
printf (" -t: generate test filter array\n");
printf (" -L: print Software License for this module\n");
exit (1);
}
void
main (argc, argv)
int argc;
char *argv[];
{
int i, j;
int nr, nc;
int jmin, imin, jmax, imax;
int left_x, right_x;
float m00;
float mu00, mu11, mu02, mu20;
float xc, yc, rg, dent;
int xdim, ydim;
float *y[MDIM], *m[MDIM];
char *buf;
int i_arg;
FILE *file;
Image *imgIn; /* input image */
/*
* cmd line options
*/
static char *optstring = "dtw:L";
/*
* parse command line
*/
optind = 2;
opterr = ON; /* give error messages */
if (argc < 2)
usage (argv[0]);
while ((i_arg = getopt (argc, argv, optstring)) != EOF) {
switch (i_arg) {
case 'd':
printf ("...option %c: default mode\n", i_arg);
FILTER_TEST = OFF;
break;
case 't':
printf ("...option %c: generate test filter array\n", i_arg);
FILTER_TEST = ON;
break;
case 'w':
printf ("...option %c: write file %s to disk\n",
i_arg, buf = optarg);
if ((file = fopen (buf, "w")) == NULL) {
puts ("\n...could not open output file");
exit (1);
}
WRITE_FILE = ON;
break;
case 'L':
print_sos_lic ();
exit (0);
default:
printf ("...unknown command line argument encountered\n");
usage (argv[0]);
exit (1);
break;
}
}
/*
* get the input image
*/
imgIn = ImageIn (argv[1]);
if (imgIn->bps == 8 && imgIn->spp == 3) {
printf ("Got RGB image!!!\n");
fprintf (stderr, "Can only work with Grayscale or Binary TIFF files!!!\n");
exit (1);
}
if (imgIn->bps != 1) {
printf ("Got Grayscale image!!!\n");
fprintf (stderr, "Can only work with Binary TIFF files!!!\n");
exit (1);
}
/* reset tiffInput so that we write a grayscale file (i.e tags are not copied) */
tiffInput = 0;
jmin = imin = 0;
jmax = imgIn->width;
imax = imgIn->height;
left_x = jmin;
right_x = jmax - 1;
nc = jmax - jmin;
nr = imax - imin;
#ifdef DEBUG
printf ("\n...nc = %d, nr = %d\n", nc, nr);
#endif
/*
* zero outer border of image
*/
zero_border (imgIn, 2);
/*
* memory allocation for filter and moment arrays
*/
xdim = ydim = MDIM;
for (j = 0; j < ydim; j++) {
if ((y[j] = (float *) calloc (xdim, sizeof (float))) == NULL)
fail_alloc ("y", 1);
}
for (j = 0; j < ydim; j++) {
if ((m[j] = (float *) calloc (xdim, sizeof (float))) == NULL)
fail_alloc ("m", 1);
}
/*
* begin moment evaluation
*/
if (FILTER_TEST == ON) { /* test filter array */
printf ("...initialize a test filter array\n\n");
for (j = 0; j < ydim; j++) {
for (i = 0; i < xdim; i++) {
if ((j == 0) || (i == 0))
*(y[j] + i) = (float) 1.0;
if ((j == 1) && (i == 1))
*(y[j] + i) = (float) 1.0;
if ((j == 1) && (i == 2))
*(y[j] + i) = (float) 1.0;
if ((j == 2) && (i == 1))
*(y[j] + i) = (float) 1.0;
if ((j == 2) && (i == 2))
*(y[j] + i) = (float) 1.0;
printf (" %2.0f ", *(y[j] + i));
if ((i + 1) % 4 == 0)
printf ("\n");
}
printf ("\n");
}
}
else /* compute filter output from given image */
filter_recursion (left_x, right_x, nr, nc, y, xdim, ydim, imgIn);
/*
* evaluate moments by matrix multiplication
*/
printf ("\n...matrix multiplication to obtain moments\n");
eval_mom (y, m, MDIM);
/*
* compute centroid and central moments
*/
central_moments (m, &mu00, &mu11, &mu02, &mu20, &xc, &yc, &rg, &dent);
/*
* print area-normalized and central moments
*/
printf ("\n...moments:\n");
m00 = *(m[0] + 0);
for (i = 0; i < (int) MDIM; i++) {
for (j = 0; j < (int) MDIM; j++) {
*(m[i] + j) /= m00;
printf (" m[%d][%d]/m00 = %f\n", i, j, *(m[i] + j));
}
}
printf (" %f\n", m00);
printf ("\n...central moments:\n");
printf ("...mu00 = %f, mu11 = %f\n", mu00, mu11);
printf ("...mu02 = %f, mu20 = %f\n", mu02, mu20);
printf ("...rg = %f\n", rg);
printf ("...dent = %f\n", dent);
/*
* write data file of format ( .mdt)
*/
if (WRITE_FILE == ON) {
write_mdt_file (file, m, (int) MDIM, m00, mu00,
mu11, mu02, mu20, xc, yc, rg, dent);
fclose (file);
}
for (j = 0; j < ydim; j++) {
free (y[j]);
free (m[j]);
}
}